package com.aruba.mvp.presenter;

import com.aruba.mvp.model.BaseModel;
import com.aruba.mvp.util.http.BaseDataCallback;
import com.aruba.mvp.util.http.GsonHelper;
import com.aruba.mvp.util.http.HttpResponse;
import com.aruba.mvp.util.http.NovateHelper;
import com.tamic.novate.Throwable;
import com.tamic.novate.callback.RxStringCallback;

import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;

/**
 * Created by aruba on 2018/2/6.
 */

public abstract class HttpPresenter extends BasePresenter {
    private static final String data_style_err = "服务器返回数据格式错误";
    private static final String token_err = "会话过期请重新登录！";
    private static final String token_err2 = "Token验证不通过！";
    
    private RxStringCallback rxResultCallback;

    private HashMap<Object, BaseDataCallback> baseDataCallbackHashMap = new HashMap<>();

    protected void realGetData(BaseModel baseModel, String url, BaseDataCallback baseDataCallback) {
        baseDataCallbackHashMap.put(url, baseDataCallback);
        realGetData(baseModel, url, null, false);
    }

    protected void realGetDataShowProgress(BaseModel baseModel, String url, BaseDataCallback baseDataCallback) {
        baseDataCallbackHashMap.put(url, baseDataCallback);
        realGetData(baseModel, url, null, true);
    }

    /**
     * 获取网络数据
     */
    protected void realGetData(BaseModel baseModel, String url, RxStringCallback rxResultCallback, boolean showLoading) {
        if (!isViewAttached()) {
            //如果没有View引用就不加载数据
            return;
        }

        if (showLoading) {
            //显示正在加载进度条
            getView().showLoading();
        }

        if (rxResultCallback == null) {
            if (this.rxResultCallback == null)
                this.rxResultCallback = getDefaultRxResultCallback();
        } else {
            this.rxResultCallback = rxResultCallback;
        }
        baseModel.execute(url, this.rxResultCallback);
    }

    private RxStringCallback defaultRxResultCallback;

    protected RxStringCallback getDefaultRxResultCallback() {
        if (defaultRxResultCallback == null) {
            defaultRxResultCallback = new RxStringCallback() {

                @Override
                public void onNext(Object tag, String responseStr) {
                    if (isViewAttached()) {
                        getView().hideLoading();
                    }

                    if (isViewAttached()) {
                        HttpResponse response = new HttpResponse();
                        JSONObject jsonObject;
                        try {
                            jsonObject = new JSONObject(responseStr);
                            response.isSuccess = jsonObject.getString("isSuccess");
                            response.info = jsonObject.getString("info");
                        } catch (JSONException e) {
                            e.printStackTrace();
                            getView().showErr((String) tag, data_style_err);
                            return;
                        }

                        BaseDataCallback baseDataCallback = baseDataCallbackHashMap.remove(tag);

                        if (response.isSuccess.equals("1")) {
                            if (baseDataCallback != null) {
                                try {
                                    response.data = jsonObject.getString("data");
                                } catch (JSONException e) {
                                }

                                if (response.data == null || (response.data != null && response.data.isEmpty())) {
                                    baseDataCallback.emptyCallBack(response.info);
                                }

                                Type entityClass = ((ParameterizedType) baseDataCallback.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
                                baseDataCallback.dataCallback(GsonHelper.getInstance().getGson().fromJson(response.data, entityClass));
                            }
                        } else {
                            if (baseDataCallback != null) {
                                if (baseDataCallback.needFailData) {
                                    try {
                                        response.data = jsonObject.getString("data");
                                        Type entityClass = ((ParameterizedType) baseDataCallback.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
                                        baseDataCallback.failDataCallBack(GsonHelper.getInstance().getGson().fromJson(response.data, entityClass));
                                    } catch (JSONException e) {
                                    }
                                }
                            }

                            if (NovateHelper.getInstance().toMainClear != null && ((response.info.equals(token_err) || response.info.equals(token_err2)))) {
                                NovateHelper.getInstance().toMainClear.toMainClear();
                            }
                            getView().showErr((String) tag, response.info);
                        }
                    }
                }

                @Override
                public void onError(Object tag, Throwable e) {
                    baseDataCallbackHashMap.remove(tag);

                    if (isViewAttached()) {
                        getView().hideLoading();
                    }

                    if (isViewAttached()) {
                        getView().showErr((String) tag, e.getMessage());
                    }
                }

                @Override
                public void onCancel(Object tag, Throwable e) {
                    baseDataCallbackHashMap.remove(tag);

                    if (isViewAttached()) {
                        getView().hideLoading();
                    }

                    if (isViewAttached()) {
                        getView().showErr((String) tag, e.getMessage());
                    }
                }

            };
        }
        return defaultRxResultCallback;
    }
}
